package tp.pr4.instructions;

import java.util.StringTokenizer;
import tp.pr4.NavigationModule;
import tp.pr4.RobotEngine;
import tp.pr4.instructions.exceptions.*;
import tp.pr4.items.ItemContainer;

/**
 * This instruction tries to pick an Item from the current place and puts it 
 * the robot inventory. This instruction works if the user writes PICK id or COGER id
 * @author Alvaro Saez Hernando
 * @author Noel Clemente Montero 
 */
public class PickInstruction implements Instruction{
	
	private static final String LINE_SEPARATOR = System.lineSeparator();
	
	private String id;
	private NavigationModule navigation;
	private ItemContainer robotContainer;
	
	/**
	 * Default constructor.
	 */
	public PickInstruction(){
		this.id=null;
	}
	
	/**
	 * Creates a PickInstruction using a ID 
	 * @param id
	 */
	public PickInstruction(String id) {
		this.id = id;

	}
	
	/**
	 * Parses the String returning an instance of PickInstruction or throwing a WrongInstructionFormatException()
	 * @param cad text String to parse
	 * @return Instruction Reference to an instance of PickInstruction
	 * @throws WrongInstructionFormatException hen the String is not PICK|COGER <id>
	 */
	public Instruction parse(String cad) throws WrongInstructionFormatException {

		StringTokenizer st = new StringTokenizer(cad, " ");
		String words = st.nextToken().toUpperCase();
		
		if ((words.equals("PICK")) || (words.equals("COGER"))) {
			if (st.hasMoreTokens()) {
				String id = st.nextToken();
				if (!st.hasMoreTokens())
					return new PickInstruction(id);
				else
					throw new WrongInstructionFormatException("WALL·E says: I do not understand. Please repeat" + LINE_SEPARATOR);
			} 
			else
				throw new WrongInstructionFormatException("WALL·E says: I do not understand. Please repeat" + LINE_SEPARATOR);
		} 
		else
			throw new WrongInstructionFormatException("WALL·E says: I do not understand. Please repeat" + LINE_SEPARATOR);
		
	}

	/**
	 * Returns a description of the Instruction syntax. The string does not 
	 * end with the line separator. It is up to the caller adding it before printing.
	 * @return the command syntax PICK|COGER <id>
	 */
	public String getHelp() {
		return "PICK | COGER <id>" + LINE_SEPARATOR;
	}

	/**
	 * Configures the context
	 * @param engine The robot engine
	 * @param navigation The information about the game, i.e., the places, current 
	 * direction and current heading to navigate
	 * @param robotContainer The inventory of the robot
	 */
	public void configureContext(RobotEngine engine,NavigationModule navigation, ItemContainer robotContainer) {
		this.navigation = navigation;
		this.robotContainer = robotContainer;
	}
	
	/**
	 * The robot adds an item to its inventory from the current place, if it exists
	 * @throws instructionExecutionException When the place does not contain an item 
	 * with this name or when there is another item with the same id in the robot inventory
     * @throws InstructionExecutionException if there exist any execution error.
	 */
	public void execute() throws InstructionExecutionException {
		
		if (id != null && navigation.findItemAtCurrentPlace(id) ){
			
			if (!robotContainer.containsItem(id))
			{				
				this.robotContainer.addItem(navigation.pickItemFromCurrentPlace(id));
				System.out.print("WALL·E says: I am happy! Now I have "+this.id + LINE_SEPARATOR);
			} 
			else throw new InstructionExecutionException("WALL·E says: I am stupid! The inventory already has the object " + id + LINE_SEPARATOR);
		}
		else throw new InstructionExecutionException("WALL·E says: place do not have any " + id + "." + LINE_SEPARATOR);
		
	}

}
